package com.xbb.service.impl;

import com.xbb.entity.Services;
import com.xbb.entity.Statistics;
import com.xbb.entity.User;
import com.xbb.mapper.ServicesMapper;
import com.xbb.mapper.UserMapper;
import com.xbb.service.RecommendService;
import com.xbb.util.RecommendUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class RecommendServiceImpl implements RecommendService {

    @Resource
    private ServicesMapper servicesMapper;
    @Resource
    private UserMapper userMapper;

    // 协同过滤推荐算法
    @Override
    public List<Services> selectListByRecommend(Integer userId, Integer limit) {
        // 当前用户下标
        int userIndex = 0;
        // 用户数据集
        List<User> userList = userMapper.selectListByField("role", 0);
        // 物品数据集
        List<Services> commodityList = servicesMapper.selectAll();
        // 用户、物品矩阵，行代表用户，列代表物品，值代表是否喜爱
        double[][] userRatings = new double[userList.size()][commodityList.size()];
        for (int k = 0; k < userList.size(); k++) {
            // 根据用户ID匹配，记录用户下标
            if (userList.get(k).getId() == userId) {
                userIndex = k;
            }
            List<Statistics> statisticsList = servicesMapper.selectListByRecommend(userList.get(k).getId());
            // 用户物品数据集
            double[] userCommodity = new double[commodityList.size()];
            for (int i = 0; i < commodityList.size(); i++) {
                // 默认不喜爱标记为0
                userCommodity[i] = 0;
                for (Statistics statistics : statisticsList) {
                    // 判断是否为喜爱物品
                    if (commodityList.get(i).getId() == statistics.getCount()) {
                        // 喜爱物品标记为1
                        userCommodity[i] = 1;
                        continue;
                    }
                }
            }
            // 用户物品数据集赋值到矩阵
            userRatings[k] = userCommodity;
        }

        // 计算后得出的推荐数据集
        Set<Services> recommendList = new HashSet<>();
        try {
            // 计算过后得出的矩阵物品下标数据集
            List<Integer> indexList = RecommendUtils.recommendItems(userIndex, userRatings, limit);
            // 遍历物品下标数据集
            for (Integer index : indexList) {
                for (int i = 0; i < commodityList.size(); i++) {
                    // 匹配对应下标
                    if (index == i + 1) {
                        // 将推荐物品添加至推荐数据集
                        recommendList.add(commodityList.get(i));
                    }
                }
            }
        } catch (Exception e) {
            List<Services> servicesList = servicesMapper.selectListByLimit("id", "desc", limit);
            recommendList = new HashSet<>(servicesList);
        }

        if (recommendList.size() == 0) {
            List<Services> servicesList = servicesMapper.selectListByLimit("id", "desc", limit);
            recommendList = new HashSet<>(servicesList);
        }

        // 如果推荐数据低于 limit 条，随机补齐
        if (recommendList.size() < limit) {
            List<Services> servicesList = servicesMapper.selectListByLimit("id", "desc", limit - recommendList.size());
            for (Services data : servicesList) {
                recommendList.add(data);
            }
        }

        return new ArrayList<>(recommendList);
    }

}
